﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace Configure
{
    public class ServiceConfig
    {
        private string configurationName { get; set; }

        public ServiceConfig(string path)
        {
            this.configurationName = path;
        }

        public IEnumerable<string> GetExecuteTimes()
        {
            return XDocument.Load(this.configurationName)
                .Element("configuration")
                .Element("customSettings")
                .Element("ExecuteTimes")
                .Descendants("time")
                .Select(r => r.Attribute("value").Value);
        }

        public void SaveExecuteTimes(IEnumerable<string> times)
        {
            var document = XDocument.Load(this.configurationName);

            document
                .Element("configuration")
                .Element("customSettings")
                .Element("ExecuteTimes")
                .Elements()
                .Remove();

            document
                .Element("configuration")
                .Element("customSettings")
                .Element("ExecuteTimes")
                .Add(times.Select(r => new XElement(
                        "time",
                        new XAttribute("value", r))));

            document.Save(this.configurationName);
        }

        public Dictionary<string, string> GetSuppliers()
        {
            var data = new Dictionary<string, string>();

            foreach (var record in XDocument.Load(this.configurationName)
                                    .Element("configuration")
                                    .Element("customSettings")
                                    .Element("suppliers")
                                    .Descendants("supplier"))
                data.Add(record.Attribute("id").Value, record.Attribute("name").Value);

            return data;
        }

        public void SaveSuppliers(Dictionary<string, string> data)
        {
            var document = XDocument.Load(this.configurationName);

            document
                .Element("configuration")
                .Element("customSettings")
                .Element("suppliers")
                .Elements()
                .Remove();

            document
                .Element("configuration")
                .Element("customSettings")
                .Element("suppliers")
                .Add(data.Select(r => new XElement(
                        "supplier",
                        new XAttribute("id", r.Key),
                        new XAttribute("name", r.Value))));

            document.Save(this.configurationName);
        }

        public Dictionary<string, string> GetSuppliersCache()
        {
            var data = new Dictionary<string, string>();

            foreach (var record in XDocument.Load(this.configurationName)
                                    .Element("configuration")
                                    .Element("appCache")
                                    .Element("suppliers")
                                    .Descendants("supplier"))
                data.Add(record.Attribute("id").Value, record.Attribute("name").Value);

            return data;
        }

        public void SaveSuppliersCache(Dictionary<string, string> data)
        {
            var document = XDocument.Load(this.configurationName);

            document
                .Element("configuration")
                .Element("appCache")
                .Element("suppliers")
                .Elements()
                .Remove();

            document
                .Element("configuration")
                .Element("appCache")
                .Element("suppliers")
                .Add(data.Select(r => new XElement(
                        "supplier",
                        new XAttribute("id", r.Key),
                        new XAttribute("name", r.Value))));

            document.Save(this.configurationName);
        }

        public Dictionary<string, string> GetCompaniesCache()
        {
            var data = new Dictionary<string, string>();

            foreach (var record in XDocument.Load(this.configurationName)
                                    .Element("configuration")
                                    .Element("appCache")
                                    .Element("companies")
                                    .Descendants("company"))
                data.Add(record.Attribute("id").Value, record.Attribute("name").Value);

            return data;
        }

        public void SaveCompaniesCache(Dictionary<string, string> data)
        {
            var document = XDocument.Load(this.configurationName);

            document
                .Element("configuration")
                .Element("appCache")
                .Element("companies")
                .Elements()
                .Remove();

            document
                .Element("configuration")
                .Element("appCache")
                .Element("companies")
                .Add(data.Select(r => new XElement(
                        "company",
                        new XAttribute("id", r.Key),
                        new XAttribute("name", r.Value))));

            document.Save(this.configurationName);
        }


        public void ConfigurationCheck()
        {
            /// Загружаем файл
            XDocument document;
            if (System.IO.File.Exists(this.configurationName))
            {
                document = XDocument.Load(this.configurationName);
            }
            else
            {
                document = new XDocument();
            }

            if (document.Element("configuration") == null)
                document.Add(new XElement("configuration"));

            if (document
                .Element("configuration")
                .Element("appSettings") == null)
                document
                    .Element("configuration")
                    .Add(new XElement("appSettings"));

            if (document
                .Element("configuration")
                .Element("appCache") == null)
                document
                    .Element("configuration")
                    .Add(new XElement("appCache"));

            if (document
                .Element("configuration")
                .Element("customSettings") == null)
                document
                    .Element("configuration")
                    .Add(new XElement("customSettings"));

            if (document
                .Element("configuration")
                .Element("appCache")
                .Element("suppliers") == null)
                document
                    .Element("configuration")
                    .Element("appCache")
                    .Add(new XElement("suppliers"));

            if (document
                .Element("configuration")
                .Element("appCache")
                .Element("companies") == null)
                document
                    .Element("configuration")
                    .Element("appCache")
                    .Add(new XElement("companies"));
            
            if (document
                .Element("configuration")
                .Element("customSettings")
                .Element("suppliers") == null)
                document
                    .Element("configuration")
                    .Element("customSettings")
                    .Add(new XElement("suppliers"));

            if (document
                .Element("configuration")
                .Element("customSettings")
                .Element("ExecuteTimes") == null)
                document
                    .Element("configuration")
                    .Element("customSettings")
                    .Add(new XElement("ExecuteTimes"));

            var settings = document
                .Element("configuration")
                .Element("appSettings");

            /// Проверка наличия полей
            if (!settings.Elements().Any(r => r.Attribute("key").Value == "1cVersion"))
                settings.Add(new XElement("add", new XAttribute("key", "1cVersion")));

            if (!settings.Elements().Any(r => r.Attribute("key").Value == "1cUseJournal"))
                settings.Add(new XElement("add", new XAttribute("key", "1cUseJournal")));            

            if (!settings.Elements().Any(r => r.Attribute("key").Value == "1cConnectionType"))
                settings.Add(new XElement("add", new XAttribute("key", "1cConnectionType")));

            if (!settings.Elements().Any(r => r.Attribute("key").Value == "1cPath"))
                settings.Add(new XElement("add", new XAttribute("key", "1cPath")));

            if (!settings.Elements().Any(r => r.Attribute("key").Value == "1cServer"))
                settings.Add(new XElement("add", new XAttribute("key", "1cServer")));

            if (!settings.Elements().Any(r => r.Attribute("key").Value == "1cRef"))
                settings.Add(new XElement("add", new XAttribute("key", "1cRef")));

            if (!settings.Elements().Any(r => r.Attribute("key").Value == "1cUser"))
                settings.Add(new XElement("add", new XAttribute("key", "1cUser")));

            if (!settings.Elements().Any(r => r.Attribute("key").Value == "1cPassword"))
                settings.Add(new XElement("add", new XAttribute("key", "1cPassword")));

            if (!settings.Elements().Any(r => r.Attribute("key").Value == "1cConnectionString"))
                settings.Add(new XElement("add", new XAttribute("key", "1cConnectionString")));

            if (!settings.Elements().Any(r => r.Attribute("key").Value == "ApiUri"))
                settings.Add(new XElement("add", new XAttribute("key", "ApiUri")));

            if (!settings.Elements().Any(r => r.Attribute("key").Value == "RootUri"))
                settings.Add(new XElement("add", new XAttribute("key", "RootUri")));

            if (!settings.Elements().Any(r => r.Attribute("key").Value == "EdexEmail"))
                settings.Add(new XElement("add", new XAttribute("key", "EdexEmail")));

            if (!settings.Elements().Any(r => r.Attribute("key").Value == "EdexPassword"))
                settings.Add(new XElement("add", new XAttribute("key", "EdexPassword")));

            if (!settings.Elements().Any(r => r.Attribute("key").Value == "EdexCompanyKey"))
                settings.Add(new XElement("add", new XAttribute("key", "EdexCompanyKey")));

            if (!settings.Elements().Any(r => r.Attribute("key").Value == "SyncDate"))
                settings.Add(new XElement("add", new XAttribute("key", "SyncDate")));

            if (!settings.Elements().Any(r => r.Attribute("key").Value == "SyncDay"))
                settings.Add(new XElement("add", new XAttribute("key", "SyncDay")));

            if (!settings.Elements().Any(r => r.Attribute("key").Value == "DeleteCommerceML"))
                settings.Add(new XElement("add", new XAttribute("key", "DeleteCommerceML")));

            if (!settings.Elements().Any(r => r.Attribute("key").Value == "Suppliers"))
                settings.Add(new XElement("add", new XAttribute("key", "Suppliers")));

            /// Сохраняем конфигурационный файл сервиса
            document.Save(this.configurationName);
        }

        public string GetValue(string attributeName)
        {
            var document = XDocument.Load(this.configurationName);
            var settings = document
                .Element("configuration")
                .Element("appSettings")
                .Elements();

            return settings.SingleOrDefault(r => r.Attribute("key").Value == attributeName).Value;
        }

        public bool GetBooleanValue(string attributeName)
        {
            bool result = false;

            var document = XDocument.Load(this.configurationName);
            var settings = document
                .Element("configuration")
                .Element("appSettings")
                .Elements();

            try
            {
                 result = bool.Parse(settings.SingleOrDefault(r => r.Attribute("key").Value == attributeName).Value);
            }
            catch (Exception ex) { }

            return result;
        }

        public int GetNumericValue(string attributeName)
        {
            var document = XDocument.Load(this.configurationName);
            var settings = document
                .Element("configuration")
                .Element("appSettings")
                .Elements();

            return int.Parse(settings.SingleOrDefault(r => r.Attribute("key").Value == attributeName).Value);
        }

        public DateTime GetDateTimeValue(string attributeName)
        {
            DateTime result = DateTime.Now;            

            var document = XDocument.Load(this.configurationName);
            var settings = document
                .Element("configuration")
                .Element("appSettings")
                .Elements();

            try
            {
                result = DateTime.Parse(settings.SingleOrDefault(r => r.Attribute("key").Value == attributeName).Value);
            }
            catch (Exception ex) { }

            return result;
        }

        public void SetValue(string attributeName, string value)
        {
            /// Загружаем файл
            var document = XDocument.Load(this.configurationName);
            var settings = document
                .Element("configuration")
                .Element("appSettings")
                .Elements();

            settings.SingleOrDefault(r => r.Attribute("key").Value == attributeName).Value = value;
            document.Save(this.configurationName);
        }

        public void SetBooleanValue(string attributeName, bool value)
        {
            /// Загружаем файл
            var document = XDocument.Load(this.configurationName);
            var settings = document
                .Element("configuration")
                .Element("appSettings")
                .Elements();

            if (value)
                settings.SingleOrDefault(r => r.Attribute("key").Value == attributeName).Value = bool.TrueString;
            else
                settings.SingleOrDefault(r => r.Attribute("key").Value == attributeName).Value = bool.FalseString;

            document.Save(this.configurationName);
        }

        public void SetNumericValue(string attributeName, int value)
        {
            /// Загружаем файл
            var document = XDocument.Load(this.configurationName);
            var settings = document
                .Element("configuration")
                .Element("appSettings")
                .Elements();

            settings.SingleOrDefault(r => r.Attribute("key").Value == attributeName).Value = value.ToString();
            document.Save(this.configurationName);
        }

        public void SetDateTimeValue(string attributeName, DateTime value)
        {
            /// Загружаем файл
            var document = XDocument.Load(this.configurationName);
            var settings = document
                .Element("configuration")
                .Element("appSettings")
                .Elements();

            settings.SingleOrDefault(r => r.Attribute("key").Value == attributeName).Value = value.ToString();
            document.Save(this.configurationName);
        }
    }
}
